{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapter 16"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup and imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import statsmodels.api as sm\n",
    "import matplotlib.pyplot as plt\n",
    "import scipy.optimize"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING *** OLE2 inconsistency: SSCS size is 0 but SSAT size is non-zero\n"
     ]
    }
   ],
   "source": [
    "nhefs_all = pd.read_excel('NHEFS.xls')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Section 16.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create the instrument, $Z$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "nhefs_all['highprice'] = (nhefs_all.price82 >= 1.5).astype('int')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll use a different subset of the data than used previously"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "restriction_cols = ['wt82', 'education', 'price82']\n",
    "missing = nhefs_all[restriction_cols].isnull().any(axis=1)\n",
    "nhefs = nhefs_all.loc[~missing]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1476, 65)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nhefs.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll check whether $Z$ (`highprice`) and $A$ (`qsmk`) are associated, that $\\Pr[A=1|Z=1] - \\Pr[A=1|Z=0] \\not = 0$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              Pr[A=1|Z=1] = 25.8%\n",
      "              Pr[A=1|Z=0] = 19.5%\n",
      "Pr[A=1|Z=1] − Pr[A=1|Z=0] =  6.3%\n"
     ]
    }
   ],
   "source": [
    "a_given_z1 = nhefs.qsmk.loc[nhefs.highprice == 1]\n",
    "a_given_z0 = nhefs.qsmk.loc[nhefs.highprice == 0]\n",
    "\n",
    "pr_a1_z1 = (a_given_z1 == 1).sum() * 1.0 / a_given_z1.shape[0]\n",
    "pr_a1_z0 = (a_given_z0 == 1).sum() * 1.0 / a_given_z0.shape[0]\n",
    "\n",
    "print(\"              Pr[A=1|Z=1] = {:>4.1f}%\".format(pr_a1_z1 * 100))\n",
    "print(\"              Pr[A=1|Z=0] = {:>4.1f}%\".format(pr_a1_z0 * 100))\n",
    "print(\"Pr[A=1|Z=1] − Pr[A=1|Z=0] = {:>4.1f}%\".format((pr_a1_z1 - pr_a1_z0) * 100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Section 16.2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Program 16.1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pg 196: For a dichotomous instrument $Z$ that also meets condition (iv) from section 16.3,\n",
    "\n",
    "$$\n",
    "    \\text{E}[Y^{a=1}] - \\text{E}[Y^{a=0}] = \\frac{\\text{E}[Y|Z=1] - \\text{E}[Y|Z=0]}{\\text{E}[A|Z=1] - \\text{E}[A|Z=0]}\n",
    "$$\n",
    "\n",
    "\"We estimated the numerator and denominator of the IV estimand by simply calculating the four sample averages ...\", pg 197"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "est_y_given_z1 = nhefs.wt82_71[nhefs.highprice == 1].mean()\n",
    "est_y_given_z0 = nhefs.wt82_71[nhefs.highprice == 0].mean()\n",
    "est_a_given_z1 = nhefs.qsmk[nhefs.highprice == 1].mean()\n",
    "est_a_given_z0 = nhefs.qsmk[nhefs.highprice == 0].mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "estimated E[Y|Z=1] = 2.686\n",
      "estimated E[Y|Z=0] = 2.536\n",
      "estimated E[A|Z=1] = 0.258\n",
      "estimated E[A|Z=0] = 0.195\n"
     ]
    }
   ],
   "source": [
    "print('estimated E[Y|Z=1] = {:>0.3f}'.format(est_y_given_z1))\n",
    "print('estimated E[Y|Z=0] = {:>0.3f}'.format(est_y_given_z0))\n",
    "print('estimated E[A|Z=1] = {:>0.3f}'.format(est_a_given_z1))\n",
    "print('estimated E[A|Z=0] = {:>0.3f}'.format(est_a_given_z0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the usual IV estimate: 2.40kg\n"
     ]
    }
   ],
   "source": [
    "estimate = (est_y_given_z1 - est_y_given_z0) / (est_a_given_z1 - est_a_given_z0)\n",
    "print('the usual IV estimate: {:>0.2f}kg'.format(estimate))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\"Equivalently, we could have fit two (saturated) linear models to estimate the differences in the denominator and the numerator...\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = sm.OLS.from_formula('wt82_71 ~ highprice', data=nhefs)\n",
    "numer = model.fit()\n",
    "\n",
    "model = sm.OLS.from_formula('qsmk ~ highprice', data=nhefs)\n",
    "denom = model.fit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the usual IV estimate: 2.40kg\n"
     ]
    }
   ],
   "source": [
    "estimate = numer.params['highprice'] / denom.params['highprice']\n",
    "print('the usual IV estimate: {:>0.2f}kg'.format(estimate))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Program 16.2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Two stage least squares estimator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we'll manually use two models, but this will give the wrong confidence interval"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = sm.OLS.from_formula('qsmk ~ highprice', data=nhefs)\n",
    "stg_1 = model.fit()\n",
    "\n",
    "nhefs['A_pred'] = stg_1.predict(nhefs)\n",
    "\n",
    "model = sm.OLS.from_formula('wt82_71 ~ A_pred', data=nhefs)\n",
    "stg_2 = model.fit()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"simpletable\">\n",
       "<tr>\n",
       "      <td></td>         <th>coef</th>     <th>std err</th>      <th>t</th>      <th>P>|t|</th>  <th>[0.025</th>    <th>0.975]</th>  \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Intercept</th> <td>    2.0682</td> <td>    5.140</td> <td>    0.402</td> <td> 0.687</td> <td>   -8.014</td> <td>   12.151</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>A_pred</th>    <td>    2.3963</td> <td>   20.055</td> <td>    0.119</td> <td> 0.905</td> <td>  -36.942</td> <td>   41.735</td>\n",
       "</tr>\n",
       "</table>"
      ],
      "text/plain": [
       "<class 'statsmodels.iolib.table.SimpleTable'>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stg_2.summary().tables[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the 2-stage estimate: 2.40kg\n"
     ]
    }
   ],
   "source": [
    "estimate = stg_2.params['A_pred']\n",
    "print('the 2-stage estimate: {:>0.2f}kg'.format(estimate))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\"A commonly used rule of thumb is to declare an instrument as weak if the F-statistic from the first-stage model is less than 10\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1st-stage F-statistic: 0.82\n"
     ]
    }
   ],
   "source": [
    "print('1st-stage F-statistic: {:>0.2f}'.format(stg_1.fvalue))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The confidence intervals in the second-stage model aren't quite right"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll do the two-stage model again, using `IV2SLS` from the `linearmodels` package"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "from linearmodels.iv import IV2SLS as lm_IV2SLS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = lm_IV2SLS.from_formula(\n",
    "    'wt82_71 ~ 1 + [qsmk ~ highprice]',\n",
    "    data=nhefs\n",
    ")\n",
    "\n",
    "two_stage = model.fit(cov_type='homoskedastic')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"simpletable\">\n",
       "<caption>Parameter Estimates</caption>\n",
       "<tr>\n",
       "      <td></td>      <th>Parameter</th> <th>Std. Err.</th> <th>T-stat</th> <th>P-value</th> <th>Lower CI</th> <th>Upper CI</th>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Intercept</th>  <td>2.0682</td>    <td>5.0817</td>   <td>0.4070</td> <td>0.6840</td>   <td>-7.8917</td>  <td>12.028</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>qsmk</th>       <td>2.3963</td>    <td>19.827</td>   <td>0.1209</td> <td>0.9038</td>   <td>-36.463</td>  <td>41.256</td> \n",
       "</tr>\n",
       "</table>"
      ],
      "text/plain": [
       "<class 'statsmodels.iolib.table.SimpleTable'>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "two_stage.summary.tables[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "         estimate   95% C.I.\n",
      "beta_1      2.40   (-36.5, 41.3)\n"
     ]
    }
   ],
   "source": [
    "# `conf_ints` is slightly different between linearmodels and statsmodels\n",
    "\n",
    "est = two_stage.params.qsmk\n",
    "conf_ints = two_stage.conf_int(level=0.95)\n",
    "lo, hi = conf_ints['lower']['qsmk'], conf_ints['upper']['qsmk']\n",
    "\n",
    "print('         estimate   95% C.I.')\n",
    "print('beta_1    {:>6.2f}   ({:>0.1f}, {:>0.1f})'.format(est, lo, hi))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Program 16.3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\"The parameters of structural mean models can be estimated via g-estimation\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll solve this using the same methods as in Program 14.2. Recall, in that program we searched for a $\\psi^\\dagger$ that would minimize the coefficient on $H(\\psi^\\dagger)$. The $\\psi^\\dagger$ that achieves the minimum is our estimate of the causal effect.\n",
    "\n",
    "In Program 14.2 we ended with a call to `scipy.optimize.minimize` to do the fine-grained search for $\\psi^\\dagger$. Here, we'll just go straight to that."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "def logit_abs_alpha(psi):\n",
    "    nhefs['H_of_psi'] = nhefs.wt82_71 - psi * nhefs.qsmk\n",
    "    gee = sm.GEE.from_formula(\n",
    "        'highprice ~ H_of_psi',\n",
    "        data=nhefs,\n",
    "        groups=nhefs.seqn,\n",
    "        family=sm.families.Binomial()\n",
    "    )\n",
    "    res = gee.fit()\n",
    "    alpha = res.params.H_of_psi\n",
    "    return abs(alpha)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This can take a while to run"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "      fun: 2.9857141760250987e-12\n",
       " hess_inv: array([[4213.9017246]])\n",
       "      jac: array([0.00061682])\n",
       "  message: 'Desired error not necessarily achieved due to precision loss.'\n",
       "     nfev: 312\n",
       "      nit: 1\n",
       "     njev: 100\n",
       "   status: 2\n",
       "  success: False\n",
       "        x: array([2.3962701])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "opt_results = scipy.optimize.minimize(\n",
    "    fun=logit_abs_alpha,\n",
    "    x0=4.0,\n",
    "    tol=1e-4\n",
    ")\n",
    "\n",
    "opt_results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "best estimate: 2.396\n"
     ]
    }
   ],
   "source": [
    "print('best estimate: {:>0.3f}'.format(opt_results.x[0]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Section 16.5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Program 16.4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll calculate the IV estimate using a few different cutoffs for `highprice`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we'll calculate the \"usual\" IV estimate using data means"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def wald_estimate(Y, A, Z):\n",
    "    numer = Y.loc[Z == 1].mean() - Y.loc[Z == 0].mean()\n",
    "    denom = A.loc[Z == 1].mean() - A.loc[Z == 0].mean()\n",
    "    return numer / denom"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cutoff price: $1.60   estimate:  41.28kg\n",
      "cutoff price: $1.70   estimate: -40.91kg\n",
      "cutoff price: $1.80   estimate: -21.10kg\n",
      "cutoff price: $1.90   estimate: -12.81kg\n"
     ]
    }
   ],
   "source": [
    "for cutoff in (1.6, 1.7, 1.8, 1.9):\n",
    "    estimate = wald_estimate(\n",
    "        nhefs.wt82_71,\n",
    "        nhefs.qsmk,\n",
    "        (nhefs.price82 >= cutoff).astype('int')\n",
    "    )\n",
    "    print('cutoff price: ${:>0.2f}   estimate: {:>6.2f}kg'.format(cutoff, estimate))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we'll re-calculate using 2-stage models, to get confidence intervals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "         estimate       95% C.I.\n",
      "$1.60      41.28   (-281.8,  364.4)\n",
      "$1.70     -40.91   (-408.6,  326.8)\n",
      "$1.80     -21.10   ( -76.8,   34.6)\n",
      "$1.90     -12.81   ( -59.2,   33.5)\n"
     ]
    }
   ],
   "source": [
    "print('         estimate       95% C.I.')\n",
    "for cutoff in (1.6, 1.7, 1.8, 1.9):\n",
    "    nhefs['highprice'] = (nhefs.price82 >= cutoff).astype('int')\n",
    "    \n",
    "    model = lm_IV2SLS.from_formula(\n",
    "        'wt82_71 ~ 1 + [qsmk ~ highprice]',\n",
    "        data=nhefs\n",
    "    )\n",
    "    res = model.fit(cov_type='homoskedastic')\n",
    "    \n",
    "    est = res.params.qsmk\n",
    "    conf_ints = res.conf_int(level=0.95)\n",
    "    lo, hi = conf_ints['lower']['qsmk'], conf_ints['upper']['qsmk']\n",
    "\n",
    "    print('${:>0.2f}     {:>6.2f}   ({:>6.1f}, {:>6.1f})'.format(cutoff, est, lo, hi))\n",
    "\n",
    "    \n",
    "# restore `highprice` to its original meaning\n",
    "nhefs['highprice'] = (nhefs.price82 >= 1.50).astype('int')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Program 16.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = lm_IV2SLS.from_formula(\n",
    "    'wt82_71 ~ 1 + sex + race + age + smokeintensity + smokeyrs' \n",
    "    '        + C(exercise) + C(active) + wt71 + [qsmk ~ highprice]',\n",
    "    data=nhefs\n",
    ")\n",
    "res = model.fit(cov_type='homoskedastic')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"simpletable\">\n",
       "<caption>Parameter Estimates</caption>\n",
       "<tr>\n",
       "          <td></td>         <th>Parameter</th> <th>Std. Err.</th> <th>T-stat</th>  <th>P-value</th> <th>Lower CI</th> <th>Upper CI</th>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Intercept</th>         <td>17.280</td>    <td>2.3259</td>   <td>7.4296</td>  <td>0.0000</td>   <td>12.722</td>   <td>21.839</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>C(exercise)[T.1]</th>  <td>0.4987</td>    <td>2.1624</td>   <td>0.2306</td>  <td>0.8176</td>   <td>-3.7395</td>  <td>4.7370</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>C(exercise)[T.2]</th>  <td>0.5818</td>    <td>2.1743</td>   <td>0.2676</td>  <td>0.7890</td>   <td>-3.6796</td>  <td>4.8433</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>C(active)[T.1]</th>    <td>-1.1701</td>   <td>0.6050</td>   <td>-1.9341</td> <td>0.0531</td>   <td>-2.3559</td>  <td>0.0156</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>C(active)[T.2]</th>    <td>-0.5123</td>   <td>1.3031</td>   <td>-0.3931</td> <td>0.6942</td>   <td>-3.0664</td>  <td>2.0418</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>sex</th>               <td>-1.6444</td>   <td>2.6201</td>   <td>-0.6276</td> <td>0.5303</td>   <td>-6.7797</td>  <td>3.4909</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>race</th>              <td>-0.1833</td>   <td>4.6314</td>   <td>-0.0396</td> <td>0.9684</td>   <td>-9.2607</td>  <td>8.8942</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>age</th>               <td>-0.1636</td>   <td>0.2396</td>   <td>-0.6831</td> <td>0.4946</td>   <td>-0.6332</td>  <td>0.3059</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>smokeintensity</th>    <td>0.0058</td>    <td>0.1449</td>   <td>0.0398</td>  <td>0.9683</td>   <td>-0.2783</td>  <td>0.2898</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>smokeyrs</th>          <td>0.0258</td>    <td>0.1608</td>   <td>0.1607</td>  <td>0.8723</td>   <td>-0.2893</td>  <td>0.3409</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>wt71</th>              <td>-0.0979</td>   <td>0.0361</td>   <td>-2.7116</td> <td>0.0067</td>   <td>-0.1687</td>  <td>-0.0271</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>qsmk</th>              <td>-1.0423</td>   <td>29.865</td>   <td>-0.0349</td> <td>0.9722</td>   <td>-59.577</td>  <td>57.492</td> \n",
       "</tr>\n",
       "</table>"
      ],
      "text/plain": [
       "<class 'statsmodels.iolib.table.SimpleTable'>"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res.summary.tables[1]"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
